﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Dracham.Classes
{
    public class Zone
    {
        public string ZoneId { get; set; }
        public string Name { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public List<Tile> Tiles { get; set; }
        public List<Object> Objects { get; set; }
        public PulseTimer Pulser { get; set; }

        public Zone()
        {
            this.Tiles = new List<Tile>();
            this.Objects = new List<Object>();
        }

        public Account[] GetCharactersInZone()
        {
            var results = GameWorld.Accounts.Where(a => a.CurrentCharacter != null);

            List<Account> chars = new List<Account>();
            foreach (Account a in results)
            {
                if (a.CurrentCharacter.Position.ZoneId == this.ZoneId)
                {
                    chars.Add(a);
                }
            }

            return chars.ToArray();
        }

        public Object[] GetCreaturesInZone()
        {
            return this.Objects.Where(o => o.GetType() == typeof(Creature)).ToArray<Object>();         
        }

        public Tile FindTile(int x, int y)
        {
            return this.FindTile((float)x, (float)y);
        }

        public Tile FindTile(float x, float y)
        {
            return this.Tiles.SingleOrDefault(t => t.Position.X == x && t.Position.Y == y);
        }

        public Tile FindTile(Position p)
        {
            if (p.ZoneId != this.ZoneId)
                return null;

            return this.Tiles.SingleOrDefault(t => t.Position.X == p.X && t.Position.Y == p.Y);
        }

        public static void LoadFromFile(String zoneFile)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(zoneFile);

            XmlNodeList zones = doc.GetElementsByTagName("Zone");

            foreach (XmlNode zoneNode in zones)
            {
                Zone z = new Zone();
                z.Name = zoneNode.Attributes["Name"].Value;
                z.ZoneId = zoneNode.Attributes["Id"].Value;
                z.Width = Convert.ToInt32(zoneNode.Attributes["Width"].Value);
                z.Height = Convert.ToInt32(zoneNode.Attributes["Height"].Value);

                GameWorld.Zones.Add(z);

                foreach (XmlNode obj in zoneNode.ChildNodes)
                {
                    if (obj.Name == "ZoneTile")
                    {
                        z.Tiles.Add(new Tile(obj, z));
                    }
                }
            }    
        }

        public static Zone GetZoneById(string zoneId)
        {
            return GameWorld.Zones.Single(z => z.ZoneId == zoneId);
        }

        public void PlayerEnterZone()
        {
            if (!GameWorld.Timers.ContainsTimer(this.Pulser))
            {
                GameWorld.Timers.AddTimer(this.Pulser);
            }
        }

        public void PlayerLeaveZone()
        {
            if (this.GetCharactersInZone().Count() == 0)
            {
                GameWorld.Timers.RemoveTimer(this.Pulser);
            }
        }
    }
}
